﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SimpleData.ObjectModel.Rules;
using SimpleData.ObjectModel.Collections;
using SimpleData.Infrastructure.Tenancy;

namespace SimpleData.ObjectModel.Design
{
	/// <summary>
	/// Representa os metadados de uma entidade do sistema
	/// </summary>
	public class Schema : IObjectPerTenant //, IRuleSchematic
	{
		#region [ .ctor ]

		/// <summary>
		/// Utilizado pelo EF
		/// </summary>
		protected Schema() // utilizado pelo EF
		{
			this.Fields = new FieldCollection( this );
			this.Rules = new SchemaRuleCollection( this );

			this.Enabled = true;
			this.WebInfo = new SchemaWebInfo();
			this.ApplicationID = 1;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="name"></param>
		/// <param name="ns"></param>
		public Schema( string name, string ns )
			: this( new SchemaName( name, ns ) )
		{ }

		/// <summary>
		/// 
		/// </summary>
		/// <param name="name"></param>
		public Schema( SchemaName name )
			: this()
		{
			//this.Fields = new DataObjectDictionary<FieldDescriptor>();
			this.Name = name;
		}

		#endregion

		/// <summary>
		/// Obtém o ID do schema
		/// </summary>
		public long SchemaID
		{ get; private set; }

		/// <summary>
		/// Obtém ou define o ID da aplicação para o qual o schema foi criado
		/// </summary>
		public long ApplicationID
		{ get; set; }

		/// <summary>
		/// Obtém ou define o nome que será exibido para o usuário
		/// </summary>
		public string DisplayName
		{ get; set; }

		/// <summary>
		/// Obtém ou define o nome que identifica unicamente a entidade
		/// </summary>
		public SchemaName Name
		{ get; private set; }

		/// <summary>
		/// Indica se o schema está habilitado
		/// </summary>
		public bool Enabled
		{ get; set; }

		/// <summary>
		/// Obtém os campos da entidade
		/// </summary>
		public FieldCollection Fields
		{ get; private set; }

		//public HybridCollection<FieldName, FieldDescriptor> Fields
		//{ get; private set; }

		public object Relations
		{ get; private set; }

		//IDataObjectName IRuleSchematic.Name
		//{
		//    get { return this.Name; }
		//}

		/// <summary>
		/// Obtém as regras do objeto
		/// </summary>
		public SchemaRuleCollection Rules
		{
			get;
			private set;
		}

		/// <summary>
		/// Obtém ou define as informações de exportação dos dados da entidade
		/// </summary>
		public SchemaWebInfo WebInfo
		{
			get;
			private set;
		}

		#region [ class SchemaWebInfo ]

		/// <summary>
		/// Informação de exportação do schema
		/// </summary>
		public class SchemaWebInfo
		{
			internal SchemaWebInfo()
			{ }

			/// <summary>
			/// Obtém ou define se a entidade é pública, pode ser acessada pela web
			/// </summary>
			public bool IsPublic
			{ get; set; }

			/// <summary>
			/// Otbém o endereço URL que é utilizado para identificar a entidade pela URL
			/// </summary>
			public string UrlFriendly
			{ get; set; }
		}

		#endregion

		#region [ class FieldCollection ]

		/// <summary>
		/// 
		/// </summary>
		public sealed class FieldCollection : HybridCollection<FieldName, FieldDescriptor>
		{

			internal FieldCollection( Schema schema )
				: base( f => f.Name )
			{
				this.Schema = schema;
			}

			/// <summary>
			/// 
			/// </summary>
			public Schema Schema
			{ get; private set; }
		}

		#endregion

		#region [ class SchemaRuleCollection ]

		/// <summary>
		/// 
		/// </summary>
		public sealed class SchemaRuleCollection : CollectionBase<SchemaRule>
		{

			internal SchemaRuleCollection( Schema schema )
			{
				this.Schema = schema;
			}

			public Schema Schema
			{ get; private set; }
		}

		#endregion
	}
}
